﻿using FlowCanvas;
using ParadoxNotion.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Yoozoo.Managers.ResourceManagerV2.Runtime;

namespace Yoozoo.Gameplay.Liberty
{
    public class GuideBlueprintManager : MonoBehaviour
    {
        [Serializable]
        public class GuideChapter
        {
            public int chapterId;
            public string chapterName;
            public string resPath;  // prefab 路径
            
            public GameObject bpInstance; // 蓝图实例

            [NonSerialized]
            public ResLoader ResLoader;
        }
        
        public List<GuideChapter> GuideChapters;
        private Dictionary<int, GuideChapter> _guideChapterMap;

        private int _currentChapterId;

        private bool _init = false;

        private List<FlowScriptController> _flowScriptControllers;

        private void Awake()
        {
            _flowScriptControllers = GetComponentsInChildren<FlowScriptController>().ToList();
        }

        public void OnInit(int chapterId)
        {
            if (_init)
            {
                return;
            }
            _init = true;
            
            _guideChapterMap = new Dictionary<int, GuideChapter>(GuideChapters.Count);
            foreach (var guideChapter in GuideChapters)
            {
                _guideChapterMap[guideChapter.chapterId] = guideChapter;
            }

            _guideChapterMap.TryGetValue(chapterId, out var c1);
            if(c1 != null) LoadChapterBlueprintImmediate(c1);

            // _guideChapterMap.TryGetValue(chapterId + 1, out var c2);
            // if(c2 != null) LoadChapterBlueprintImmediate(c2);
            JSONSerializer.FlushMem();
        }

        public void OnUpdateChapter(int chapterId)
        {
            if (!_init)
            {
                return;
            }
            
            if (chapterId == _currentChapterId)
            {
                return;
            }
            
            // _guideChapterMap.TryGetValue(chapterId - 1, out var c1);
            // DestroyChapterBlueprint(c1);
            // JSONSerializer.FlushMem();
            //
            // _guideChapterMap.TryGetValue(chapterId + 1, out var c2);
            // if(c2 != null) LoadChapterBlueprintASync(c2); 
        }

        public void LoadChapterBlueprintImmediate(GuideChapter guideChapter)
        {
            UMTResource.LoadAssetRapid(guideChapter.resPath, (assetName, asset, duration, data) =>
            {
                var go = asset as GameObject;
                guideChapter.bpInstance = Instantiate(go, this.transform);
            });
        }

        public void LoadChapterBlueprintASync(GuideChapter guideChapter)
        {
            ResLoader resLoader = ResLoader.Alloc();
            resLoader.forceRelease = true;
            resLoader.Add2Load(guideChapter.resPath, typeof(GameObject), ((success, assetName, asset) =>
            {
                if (!success)
                {
                    return;
                }
                guideChapter.bpInstance = GameObject.Instantiate(asset as GameObject, this.transform);
            }));
            resLoader.Load();
            guideChapter.ResLoader = resLoader;
        }

        public void DestroyChapterBlueprint(GuideChapter guideChapter)
        {
            if (guideChapter!=null && guideChapter.bpInstance!=null)
            {
                GameObject.DestroyImmediate(guideChapter.bpInstance);
                guideChapter.bpInstance = null;

                if (guideChapter.ResLoader!=null)
                {
                    guideChapter.ResLoader.Recycle2Cache();
                    guideChapter.ResLoader = null;
                }
                else
                {
                    UMTResource.UnloadAssetImmediately(guideChapter.resPath);
                }
            }
        }

        public void OnLogOut()
        {
            if (_flowScriptControllers != null)
            {
                foreach (var controller in _flowScriptControllers)
                {
                    controller.RestartBehaviour();
                }
            }

            _init = false;
            _currentChapterId = 0;

            foreach (var guideChapter in GuideChapters)
            {
                if (guideChapter.bpInstance)
                {
                    DestroyChapterBlueprint(guideChapter);
                }
            }
            
        }
    }
}
